package flc.ast.fragment;

import android.Manifest;
import android.os.Build;
import android.os.Bundle;

import androidx.annotation.RequiresApi;
import androidx.fragment.app.Fragment;

import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.blankj.utilcode.util.FileUtils;
import com.blankj.utilcode.util.ToastUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.OptionalDouble;

import flc.ast.R;
import flc.ast.databinding.FragmentTestBinding;
import flc.ast.utils.Content;
import flc.ast.utils.MyMediaRecorder;
import stark.common.basic.base.BaseNoModelFragment;
import stark.common.basic.utils.FileUtil;
import stark.common.basic.utils.StkPermissionHelper;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link TestFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class TestFragment extends BaseNoModelFragment<FragmentTestBinding> {

    private boolean isStart = false;
    private MyMediaRecorder mRecorder;
    private ArrayList<Integer> arrayList = new ArrayList<>();
    private boolean hasRecord = false;
    private Handler mHandler;
    float volume = 10000;

    private final Runnable mTaskUpdateTime = new Runnable() {
        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        public void run() {
            if (!hasRecord) return;
            volume = mRecorder.getMaxAmplitude();  //获取声压值
            if (volume > 0 && volume < 1000000) {
                float value = 20 * (float) (Math.log10(volume));
                int val = (int) value;
                mDataBinding.tvDecibelNumber.setText(val + getString(R.string.decibel_score));
                arrayList.add(new Integer(val));
                mDataBinding.myCpv.setProgress(val);
                setView();
                if (val < 30) {
                    mDataBinding.tvDecibelTip.setText(R.string.decibel_tip1);
                } else if (val < 60) {
                    mDataBinding.tvDecibelTip.setText(R.string.decibel_tip2);
                } else if (val < 90) {
                    mDataBinding.tvDecibelTip.setText(R.string.decibel_tip3);
                } else {
                    mDataBinding.tvDecibelTip.setText(R.string.decibel_tip4);
                }
            }
            mHandler.postDelayed(this, 1000);
        }
    };

    @Override
    protected int onCreate() {
        return R.layout.fragment_test;
    }

    @Override
    protected void initView() {
        mDataBinding.tvStartMeasure.setOnClickListener(this);

        mRecorder = new MyMediaRecorder();
        mHandler = new Handler();
    }

    @Override
    protected void onClickCallback(View v) {
        switch (v.getId()) {
            case R.id.tvStartMeasure://开始测量
                if (isStart) {
                    isStart = false;
                    stopTime();
                    mDataBinding.tvStartMeasure.setText(R.string.start_measure);
                    mDataBinding.myCpv.setProgress(0);
                } else {
                    getPermission();
                }
        }
    }

    @Override
    protected void initData() {
        mDataBinding.tvDecibelNumber.setText(0 + getString(R.string.decibel_score));
    }

    //获取权限
    private void getPermission() {
        StkPermissionHelper.permission(Manifest.permission.RECORD_AUDIO)
                .reqPermissionDesc(getString(R.string.get_audio_permission))
                .callback(new StkPermissionHelper.ACallback() {
                    @Override
                    public void onGranted() {
                        isStart = true;
                        mDataBinding.tvStartMeasure.setText(R.string.stop_measure);
                        startTest();
                    }
                }).request();
    }

    //开始检测
    private void startTest() {
        String musicPath = FileUtil.generateFilePath(Content.Temp, ".mp3");
        try {
            mRecorder.setMyRecAudioFile(FileUtils.getFileByPath(musicPath));
            if (mRecorder.startRecorder()) {
                arrayList.clear();
                hasRecord = true;
                startTime();
            } else {
                ToastUtils.showShort(R.string.audio_fail_tips);
            }
        } catch (Exception e) {
            ToastUtils.showShort(R.string.audio_fail_tips2);
            e.printStackTrace();
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    private void setView() {
        int max = Collections.max(arrayList);
        int min = Collections.min(arrayList);
        OptionalDouble avgAge = arrayList.stream().mapToInt(Integer::intValue).average();
        int avg = (int) avgAge.getAsDouble();
        mDataBinding.tvDecibelMin.setText(String.valueOf(min));
        mDataBinding.tvDecibelMax.setText(String.valueOf(max));
        mDataBinding.tvDecibelAverage.setText(String.valueOf(avg));
    }

    private void startTime() {
        mHandler.post(mTaskUpdateTime);
    }

    private void stopTime() {
        mHandler.removeCallbacks(mTaskUpdateTime);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        isStart = false;
        stopTime();
        mDataBinding.tvStartMeasure.setText(R.string.start_measure);
        mDataBinding.myCpv.setProgress(0);
    }

    @Override
    public void onStop() {
        super.onStop();
        isStart = false;
        stopTime();
        mDataBinding.tvStartMeasure.setText(R.string.start_measure);
        mDataBinding.myCpv.setProgress(0);
    }
}